package com.ww.springboot.boot.thread.study.base.lock.aqs.Demo1;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * 描述：
 *
 * @author 🧑 ‍wanwei
 * @since 2023-02-13 09:29
 */
public class MyLock implements Lock {

    private MyAqs myAqs = new MyAqs();

    @Override
    public void lock() {
        System.out.println("加锁");
        //加锁
        myAqs.acquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        System.out.println("加锁 响应中断");
        //加锁 响应中断
        myAqs.acquireInterruptibly(1);
    }

    @Override
    public boolean tryLock() {
        //尝试获取锁
        return false;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        //尝试获取锁加等待时间
        return false;
    }

    @Override
    public void unlock() {
        //解锁
        myAqs.tryRelease(0);
    }

    @Override
    public Condition newCondition() {
        //创建条件队列 --不同条件队列间也有竞争
        return null;
    }

    //独占锁 只需要实现这两个方法即可
    public class MyAqs extends AbstractQueuedSynchronizer{


        /**
         * 需要自己实现 是否获取到锁
         * 如果获取不到锁 则同步器会自动将其加入到同步队列中自旋 直到获取锁为止
         * @param arg
         * @return
         */
        @Override
        protected boolean tryAcquire(int arg) {
            //1.获取当前线程
            Thread thread = Thread.currentThread();
            //2.获取当前获取锁的线程
            Thread exclusiveOwnerThread = getExclusiveOwnerThread();
            if(thread == exclusiveOwnerThread){
                //实现可重入
                return true;
            }
            //同步器state 默认是0
            if(super.compareAndSetState(0,arg)){
                return true;
            }
            return false;
        }

        @Override
        protected boolean tryRelease(int arg) {
            super.setState(0);
            return true;
        }
    }
}
